package com.onpositive.gamemaker.rcp.environment;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.swt.widgets.Shell;



@SuppressWarnings("restriction")
public class WorkspaceLocationSelector
{

	// the name of the file that tells us that the workspace directory belongs
	// to our application
	public static final String WS_IDENTIFIER = ".our_rcp_workspace";

	public static URL promptForWorkspace(Shell shell,
			ChooseWorkspaceData launchData, boolean force)
	{
		URL url = null;
		do
		{
			// okay to use the shell now - this is the splash shell
			final ChooseWorkspaceDialog chooseWorkspaceDialog = new ChooseWorkspaceDialog(shell, launchData, false, true);
			chooseWorkspaceDialog.prompt(force);
			if (chooseWorkspaceDialog.getReturnCode() == ChooseWorkspaceDialog.CANCEL)
				return null;
			String instancePath = launchData.getSelection();
			if (instancePath == null)
			{
				return null;
			}

			// the dialog is not forced on the first iteration, but is on every
			// subsequent one -- if there was an error then the user needs to be
			// allowed to fix it
			force = true;

			// 70576: don't accept empty input
			if (instancePath.length() <= 0)
			{
				MessageDialog
						.openError(
								shell,
								IDEWorkbenchMessages.IDEApplication_workspaceEmptyTitle,
								IDEWorkbenchMessages.IDEApplication_workspaceEmptyMessage);
				continue;
			}

			// create the workspace if it does not already exist
			File workspace = new File(instancePath);
			if (!workspace.exists())
			{
				boolean mkdir = workspace.mkdir();
				if (!mkdir){
					throw new RuntimeException("unable to create:"+workspace);
				}
			}

			try
			{
				// Don't use File.toURL() since it adds a leading slash that
				// Platform does not
				// handle properly. See bug 54081 for more details.
				String path = workspace.getAbsolutePath().replace(
						File.separatorChar, '/');
				url = new URL("file", null, path); //$NON-NLS-1$
			} catch (MalformedURLException e)
			{
				MessageDialog
						.openError(
								shell,
								IDEWorkbenchMessages.IDEApplication_workspaceInvalidTitle,
								IDEWorkbenchMessages.IDEApplication_workspaceInvalidMessage);
				continue;
			}
		} while (!checkValidWorkspace(shell, url));

		return url;
	}

	private static boolean checkValidWorkspace(Shell shell, URL url)
	{
		final String result = checkWorkspaceDirectory(shell, url.getPath(),
				true, false);
		if (result == null)
			return true;
		else
		{
			MessageDialog.openError(shell, "Error selecting directory", result);
			return false;
		}
	}

	/**
	 * Ensures a workspace directory is OK in regards of reading/writing, etc.
	 * This method will get called externally as well.
	 * 
	 * @param parentShell
	 *            Shell parent shell
	 * @param workspaceLocation
	 *            Directory the user wants to use
	 * @param askCreate
	 *            Whether to ask if to create the workspace or not in this
	 *            location if it does not exist already
	 * @param fromDialog
	 *            Whether this method was called from our dialog or from
	 *            somewhere else just to check a location
	 * @return null if everything is ok, or an error message if not
	 */
	public static String checkWorkspaceDirectory(Shell parentShell,
			String workspaceLocation, boolean askCreate, boolean fromDialog)
	{
		File f = new File(workspaceLocation);
		if (!f.exists())
		{
			if (askCreate)
			{
				boolean create = MessageDialog
						.openConfirm(parentShell, "New Directory",
								"The directory does not exist. Would you like to create it?");
				if (create)
				{
					try
					{
						boolean mkdirs = f.mkdirs();
						File wsDot = new File(workspaceLocation
								+ File.separator + WS_IDENTIFIER);
						boolean createNewFile = wsDot.createNewFile();
						if (!createNewFile){
							if (!mkdirs){
								return "Error creating folders for:"+wsDot+", please check folder permissions";	
							}
							return "Error creating file:"+wsDot+", please check folder permissions";
						}
					} catch (Exception err)
					{
						return "Error creating directories, please check folder permissions";
					}
				}

				if (!f.exists())
				{
					return "The selected directory does not exist";
				}
			}
		}

		if (!f.canRead())
		{
			return "The selected directory is not readable";
		}

		if (!f.isDirectory())
		{
			return "The selected path is not a directory";
		}

		File wsTest = new File(workspaceLocation + File.separator
				+ WS_IDENTIFIER);
		if (fromDialog)
		{
			if (!wsTest.exists())
			{
				boolean create = MessageDialog
						.openConfirm(
								parentShell,
								"New Workspace",
								"The directory '"
										+ wsTest.getAbsolutePath()
										+ "' is not set to be a workspace. Do note that files will be created directly under the specified directory and it is suggested you create a directory that has a name that represents your workspace. \n\nWould you like to create a workspace in the selected location?");
				if (create)
				{
					try
					{
						boolean mkdirs = f.mkdirs();
						File wsDot = new File(workspaceLocation
								+ File.separator + WS_IDENTIFIER);
						boolean createNewFile = wsDot.createNewFile();
						if (!createNewFile){
							if (mkdirs){
								return "Error creating dirs for "+f+", please check folder permissions";	
							}
							return "Error creating file "+wsDot+", please check folder permissions";	
						}
					} catch (Exception err)
					{
						return "Error creating directories, please check folder permissions";
					}
				} else
				{
					return "Please select a directory for your workspace";
				}

				if (!wsTest.exists())
				{
					return "The selected directory does not exist";
				}

				return null;
			}
		} else
		{
			try
			{
				boolean mkdirs = f.mkdirs();
				File wsDot = new File(workspaceLocation
						+ File.separator + WS_IDENTIFIER);
				if (!wsDot.exists()&&!wsDot.createNewFile()){
					System.err.println();
					if (!mkdirs){
						throw new RuntimeException("unable to create directories for:"+wsDot);	
					}
					throw new RuntimeException("unable to create :"+wsDot);
				}
			} catch (IOException err)
			{
				return "The selected directory is not a workspace directory";
			}
			return null;
		}

		return null;
	}
	
	/**
     * Return true if a valid workspace path has been set and false otherwise.
     * Prompt for and set the path if possible and required.
     * 
     * @return true if a valid instance location has been set and false
     *         otherwise
     */
	@SuppressWarnings("restriction")
	public static boolean checkInstanceLocation(Shell shell) {
        // -data @none was specified but an ide requires workspace
        Location instanceLoc = Platform.getInstanceLocation();
        if (instanceLoc == null) {
            MessageDialog
                    .openError(
                            shell,
                            IDEWorkbenchMessages.IDEApplication_workspaceMandatoryTitle,
                            IDEWorkbenchMessages.IDEApplication_workspaceMandatoryMessage);
            return false;
        }

        // -data "/valid/path", workspace already set
        if (instanceLoc.isSet()) {
            // make sure the meta data version is compatible (or the user has
            // chosen to overwrite it).
            if (!checkValidWorkspace(shell, instanceLoc.getURL())) {
				return false;
			}

            // at this point its valid, so try to lock it and update the
            // metadata version information if successful
            try {
                if (instanceLoc.lock()) {
                    return true;
                }
                
                // we failed to create the directory.  
                // Two possibilities:
                // 1. directory is already in use
                // 2. directory could not be created
                File workspaceDirectory = new File(instanceLoc.getURL().getFile());
                if (workspaceDirectory.exists()) {
	                MessageDialog.openError(
	                        shell,
	                        IDEWorkbenchMessages.IDEApplication_workspaceCannotLockTitle,
	                        IDEWorkbenchMessages.IDEApplication_workspaceCannotLockMessage);
                } else {
                	MessageDialog.openError(
                			shell, 
                			IDEWorkbenchMessages.IDEApplication_workspaceCannotBeSetTitle,
                			IDEWorkbenchMessages.IDEApplication_workspaceCannotBeSetMessage);
                }
            } catch (IOException e) {
/*                Activator.getDefault().getLog().log("Could not obtain lock for workspace location", //$NON-NLS-1$
                        e);            	*/
                MessageDialog
                .openError(
                        shell,
                        IDEWorkbenchMessages.InternalError,
                        e.getMessage());                
            }            
            return false;
        }

        // -data @noDefault or -data not specified, prompt and set
        ChooseWorkspaceData launchData = WorkspaceLocationProvider.getLaunchData();

        boolean force = false;
        while (true) {
            URL workspaceUrl = promptForWorkspace(shell, launchData, force);
            if (workspaceUrl == null) {
				return false;
			}

            // if there is an error with the first selection, then force the
            // dialog to open to give the user a chance to correct
            force = true;

            try {
                // the operation will fail if the url is not a valid
                // instance data area, so other checking is unneeded
                if (instanceLoc.setURL(workspaceUrl, true)) {
                    launchData.writePersistedData();
                    return true;
                }
            } catch (IllegalStateException e) {
                MessageDialog
                        .openError(
                                shell,
                                IDEWorkbenchMessages.IDEApplication_workspaceCannotBeSetTitle,
                                IDEWorkbenchMessages.IDEApplication_workspaceCannotBeSetMessage);
                return false;
            }

            // by this point it has been determined that the workspace is
            // already in use -- force the user to choose again
            MessageDialog.openError(shell, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle, 
                    IDEWorkbenchMessages.IDEApplication_workspaceInUseMessage);
        }
    }



}
